import { differenceBy, uniqBy, differenceWith } from 'lodash-es'
import { useBasicInfoStore } from './blocks/basicInfo/store'
import { useMeetingParamsStore } from './blocks/meetingParams/store'
import { useUserAllStore } from './blocks/user/all/store'
import Alert, { confirmModal } from '@/components/Alert'
import { PublicSaveMeetingParams, SaveMeetingParams, SaveTemplateParams, UserEntity } from '@/api/create/interface'
import { UserModel } from './blocks/user/interface'
import { TranslatorAllToSimple, getItemInAll, setSearchStatusInSimple } from './blocks/user/utils'
import { useUserOftenStore } from './blocks/user/often/store'
import { useUserStore } from './blocks/user/store'
import { useMeetingDcsStore } from './blocks/dcs/store'
import { useMeetingLiveVideoStore } from './blocks/liveVideo/store'
import { useMeetingMixStore } from './blocks/mix/store'
import { useMeetingPollStore } from './blocks/poll/store'
import { useMeetingVmpStore } from './blocks/vmp/store'
import { useMeetingTVWallStore } from './blocks/tvwall/store'
import { ITab, useCreateContentStore } from './store'
import { getUTF8ByteCount, regexEnum } from '@/utils'
import { fetchCheckTemplateName } from '@/api/create'
import { checkRule } from './rules'
import { useMeetingAiStore } from './blocks/ai/store'
import dayjs from '@/plugins/dayjs'
import { t } from 'i18next'
import { getVmpParam } from './blocks/vmp/store.combine'
import { useGlobalStore } from '@/store/global'
import { checkTvwallData, getTvwallParam, setBatchPollMemeberCash } from './blocks/tvwall/store.combine'
import { useUserInteractiveStore } from './blocks/user/interactive/store'

/** 获取所有会议参数*/
export const getAllParams = () => {
	const basicInfo = useBasicInfoStore.getState()
	const paramInfo = useMeetingParamsStore.getState()
	const { isTemplate, meetingFormKey, preKey } = useCreateContentStore.getState()

	let publicData: PublicSaveMeetingParams = {
		name: basicInfo.name,
		preoccupy_resource: paramInfo.meetingType === 2 ? 2 : paramInfo.sourceUsed,
		telephone: basicInfo.phoneNO,
		password: paramInfo.password,
		mobile: basicInfo.mobilePhone,
		encrypted_type: paramInfo.meetingType === 2 ? 2 : paramInfo.encryptedSM ? 4 : paramInfo.encryptionType,
		conf_type: paramInfo.meetingType,
		doubleflow: paramInfo.sendDoubleFlowAtOnce ? 1 : 0,
		silence: 0,
		mute: paramInfo.initMute ? 1 : 0,
		one_reforming: paramInfo.meetingType === 2 ? 0 : paramInfo.oneReforming ? 1 : 0,
		call_times: paramInfo.callTimesUnlimited ? 0 : parseInt(paramInfo.callTimes),
		call_interval: parseInt(paramInfo.callInterval),
		call_mode: paramInfo.meetingType === 2 ? 2 : paramInfo.callMode,
		safe_conf: paramInfo.meetingSafe ? 1 : 0,
		closed_conf: paramInfo.closedMeeting ? 1 : 0,
		duration: basicInfo.permanentMeeting ? 0 : basicInfo.hour * 60 + basicInfo.minute,
		conf_protocol: paramInfo.meetingType === 2 ? 2 : paramInfo.meetingProtocol,
		conf_category: 0,
		cascade_mode: paramInfo.meetingType === 2 ? 1 : paramInfo.simpleCascade ? 1 : 0,
		cascade_return_para: parseInt(paramInfo.cascadeReturnPara),
		cascade_return: paramInfo.cascadeReturn ? 1 : 0,
		cascade_upload: paramInfo.cascadeUpload ? 1 : 0,
		force_mute: 0,
		fec_mode: paramInfo.meetingType === 2 ? 0 : paramInfo.fecMode ? 1 : 0,
		enable_rtc: paramInfo.enableRtc ? 1 : 0,
		encrypted_key: paramInfo.encryptedKey,
		mute_filter: paramInfo.muteException ? 1 : 0,
		voice_activity_detection: paramInfo.meetingType === 2 ? 0 : paramInfo.voiceInspireEnable ? 1 : 0,
		quantum_encryption: paramInfo.quantumEncryption ? 1 : 0,
		public_conf: 0,
		anonymous_mt: paramInfo.allowAnonymousMt ? 1 : 0,
		auto_end: 1,
		multi_stream: paramInfo.multiStream ? 1 : 0,
		watermark: paramInfo.watermark ? 1 : 0,
		video_quality: paramInfo.meetingType === 2 ? 0 : paramInfo.videoQuality,
		dual_mode: paramInfo.doubleFlowLimit,
		vacinterval: paramInfo.voiceInspireTime,
		encrypted_auth: paramInfo.encryptedAuth ? 1 : 0,
		enable_audience: basicInfo.superMtNum ? 1 : 0,
		smart_cascade_mode: paramInfo.simpleCascade === 2 ? 1 : 0,
		max_join_mt: 192,
		video_formats: [
			{
				bitrate: paramInfo.rate ?? 2048,
				resolution: paramInfo.resolution,
				format: paramInfo.video,
				frame: paramInfo.frame,
			},
		],
		vips: basicInfo.vipList,
		keep_calling_members: paramInfo.keep_calling_members,
		speaker: basicInfo.speaker.uid === '' ? undefined : basicInfo.speaker,
		chairman: basicInfo.manager.uid === '' ? undefined : basicInfo.manager,
		invite_members: useUserAllStore.getState().getUsers(basicInfo.superMtNum),
		often_mts: useUserOftenStore.getState().getUsers(),
		//音频格式列表，不填默认支持所有，空列表默认支持所有  创会的时候不传递给后台  修改会议的时候需传递
		audio_formats: paramInfo.audio_formats,
		ai: useMeetingAiStore.getState().getAiData(),
		mix:
			paramInfo.meetingType === 2
				? undefined
				: (useMeetingMixStore.getState().getMixData(basicInfo.repeat) as any),
		poll: paramInfo.meetingType === 2 ? undefined : useMeetingPollStore.getState().getPollData(basicInfo.repeat),
		dcs: paramInfo.meetingType === 2 ? undefined : useMeetingDcsStore.getState().getDcsData(),
		recorder: useMeetingLiveVideoStore.getState().getVideoLiveData(),
		vmp: getVmpParam('save'),
		tv_wall: getTvwallParam() as any,
	}
	if (isTemplate) {
		return {
			conf_level: '',
			e164: basicInfo.preAssignedMeetingNumber,
			bitrate: paramInfo.rate,
			bind_e164: basicInfo.preAssignedMeetingCheck ? 1 : 0,
			...publicData,
		} as SaveTemplateParams
	} else {
		return {
			meeting_form_key: meetingFormKey,
			prekey: preKey,
			start_time: dayjs(basicInfo.day + ' ' + basicInfo.startTime)
				.tz()
				.format(),
			brief: basicInfo.brief,
			sms: basicInfo.notifyMode.sms ? 1 : 0,
			wechat: basicInfo.notifyMode.wechat ? 1 : 0,
			email: basicInfo.notifyMode.email ? 1 : 0,
			meeting_formular: basicInfo.meetingFormular
				? {
						start_date: dayjs(basicInfo.day + ' ' + basicInfo.startTime).format('YYYY-MM-DD'),
						week_days: basicInfo.meetingFormular.weekDays ?? '',
						end_date: basicInfo.meetingFormular.endTime
							? dayjs(basicInfo.meetingFormular.endTime + ' 21:00')
									.tz()
									.format('YYYY-MM-DD')
							: '',
						repeat_type: 7,
						frequency: 1,
				  }
				: undefined,
			meeting_criteria_list: basicInfo.meetingCriteriaList,
			...publicData,
		} as SaveMeetingParams
	}
}
export const transMeetingParamsToTemplateParams = (data: SaveMeetingParams) => {
	const {
		start_time,
		brief,
		sms,
		wechat,
		email,
		meeting_formular,
		meeting_criteria_list,
		meeting_form_key,
		prekey,
		...basicParams
	} = data //过滤出公共数据
	let _data: SaveTemplateParams = {
		conf_level: '',
		e164: '',
		bitrate: useMeetingParamsStore.getState().rate ?? 2048,
		bind_e164: 0,
		...basicParams,
	}

	filterMeetingRoom(_data.invite_members) //保存为个人模板时将会议室剔除
	filterMeetingRoom(_data.vips) //将vip列表中的会议室剔除
	_data.mix?.members && filterMeetingRoom(_data.mix.members) //将混音中的会议室剔除
	_data.poll?.members && filterMeetingRoom(_data.poll.members) //将轮询中的会议室剔除
	_data.recorder?.live_members && filterMeetingRoom(_data.recorder.live_members) //将直播中的会议室剔除
	//todo 将电视墙中的会议室剔除

	filterMeetingRoom(_data.vmp.members as any) //将画面合成中的会议室剔除
	_data.vmp.members.forEach((item) => {
		if (item.poll?.members) {
			filterMeetingRoom(item.poll.members) //将画面合成单通道轮询中的会议室剔除
		}
	})
	_data.vmp.poll && filterMeetingRoom(_data.vmp.poll.members) //将画面合成轮询中的会议室剔除

	return _data
}

//过滤会议室
const filterMeetingRoom = (members: { account_type: number }[]) => {
	return members.filter((item) => item.account_type !== 2)
}

const isTabHide = (value: ITab) => {
	const tabData = useCreateContentStore.getState().tabData
	return tabData.find((item) => item.value === value)?.hidden ?? false
}

export const checkData = async () => {
	const { brief, hour, minute, permanentMeeting, name, update, mobilePhone } = useBasicInfoStore.getState()
	const { meetingType, _meetingTypeList } = useMeetingParamsStore.getState()
	const { isTemplate, meetingMoid, resources } = useCreateContentStore.getState()
	if (!name) {
		Alert(isTemplate ? t('模板名称不能为空') : t('会议名称不能为空'))
		return false
	}
	if (useGlobalStore.getState().SWITCH.characterLimit) {
		if (!regexEnum.nameIllegal.test(name)) {
			Alert(isTemplate ? t('模板名称存在非法字符，请重新输入') : t('会议名称存在非法字符，请重新输入'))
			return false
		} else if (!/^[\u4e00-\u9fa5A-Za-z0-9]/.test(name) || !/[\u4e00-\u9fa5A-Za-z0-9]$/.test(name)) {
			Alert(t('首尾字符仅允许输入：英文、数字、汉字'))
			return false
		}
	} else {
		let len = getUTF8ByteCount(name)
		if (len > 100) {
			Alert(t('输入内容超过长度限制'))
			return false
		}
	}
	let flag = true
	if (isTemplate) {
		let res = await fetchCheckTemplateName(name, meetingMoid)
		flag = !!res.success
	} else {
		let res = await useBasicInfoStore.getState().checkMeetingName()
		flag = res
	}
	if (!flag) {
		Alert(isTemplate ? t('模板名称已存在') : t('会议名称已存在'))
		return false
	}

	if (
		useGlobalStore.getState().SWITCH.characterLimit &&
		mobilePhone !== undefined &&
		!(mobilePhone.length === 11 || mobilePhone.length === 0)
	) {
		Alert(t('手机号码应为11个字符'))
		return false
	}

	if (!_meetingTypeList.find((item) => item.value === meetingType)) {
		Alert(t('会议类型不能为空，请重新选择'))
		return false
	}

	if (resources.used >= resources.total) {
		Alert(t('当前剩余的可用会议资源不足，请检查用户域配置'))
		return false
	}

	if (brief.length > 500) {
		Alert(t('会议概要最多可输入500个字'))
		return false
	}
	if (hour === 0 && minute === 0 && !permanentMeeting) {
		Alert(t('会议时长不能为0'))
		update({ hour: 4, minute: 0 })
		return false
	}
	if (
		(!isTabHide('vl') && !useMeetingLiveVideoStore.getState().checkData()) ||
		(!isTabHide('mix') && !useMeetingMixStore.getState().checkData()) ||
		(!isTabHide('poll') && !useMeetingPollStore.getState().checkData()) ||
		(!isTabHide('vmp') && !useMeetingVmpStore.getState().checkVmpPollData()) ||
		(!isTabHide('tvwall') && !checkTvwallData())
	) {
		return false
	}

	return checkRule()
}

/** 校验规模 1-通过 2-超过视频会议规模  3-SM1加密且超过80方*/
export const checkScale = (num?: number) => {
	const superMtNum = useBasicInfoStore.getState().superMtNum
	const rootList = useUserAllStore.getState().tree
	const outerEmailMts = rootList.filter((x) => x.mcc.account_type === 4)
	const interactiveUsers = rootList.filter((x) => x.mcc.interactive_mt === 1)
	let length = rootList.length - outerEmailMts.length
	if (num) {
		//添加的是会议室
		length = num - outerEmailMts.length
	}
	if (superMtNum) {
		//超大方判断互动终端
		length = interactiveUsers.length - outerEmailMts.length
	}

	if (length > 190) {
		//超过视频会议规模
		return 2
	} else if (length > 80 && useMeetingParamsStore.getState().encryptedSM) {
		//SM1加密且超过80方
		return 3
	} else {
		//没有超过会议规模
		return 1
	}
}

export const showOverScaleDialogSave = (callBack: Function, msg?: React.ReactNode) => {
	confirmModal({
		msg: msg ?? t('添加的与会方数已超过当前会议规模，部分终端可能无法正常入会'),
		okText: t('继续邀请'),
		cancelText: t('返回修改'),
		onOk: () => {
			callBack()
		},
	})
}

/** 重置所有参数 */
export const resetAllParams = () => {
	useCreateContentStore.getState().reset()
	useBasicInfoStore.getState().reset()
	useMeetingParamsStore.getState().reset()
	useMeetingDcsStore.getState().reset()
	useMeetingAiStore.getState().reset()
	useMeetingLiveVideoStore.getState().reset()
	useMeetingPollStore.getState().reset()
	useMeetingMixStore.getState().reset()
	useMeetingTVWallStore.getState().reset()
	useMeetingVmpStore.getState().reset()
}

export const canAdd = (user: UserEntity) => {
	const superMtNum = useBasicInfoStore.getState().superMtNum
	if ((superMtNum && user.interactive_mt) || !superMtNum) {
		return true
	}
	return false
}

export const setVipList = (list: UserEntity[]) => {
	const { vipList, superMtNum } = useBasicInfoStore.getState()
	//可能是常用终端直接拖过来，所以只能遍历下看下是否存在于本级
	const tree = useUserAllStore.getState().tree
	const uuids = tree.map((x) => x.uuid)
	list = list.filter((x) => canAdd(x) && uuids.includes(`${x.account_type}$$${x.account}`) && x.account_type !== 10)
	let result = uniqBy(list, (x) => `${x.account_type}$$${x.account}`)
	if (result.length > 20) {
		Alert(t('VIP终端数量不得超过20个'))
		return
	}
	let addList = differenceBy(result, vipList, (x) => `${x.account_type}$$${x.account}`)
	useBasicInfoStore.setState({ vipList: result })

	//设置新增的vip同时变为常用
	if (!superMtNum) {
		const uuids = addList.map((x) => `${x.account_type}$$${x.account}`)
		if (uuids.length > 0) {
			let r: UserModel[] = []
			getItemInAll(tree, (item) => {
				if (uuids.includes(item.uuid)) {
					item.status.isOften = true
					r.push(item)
				}
			})
			//更新all
			useUserAllStore.setState({ tree: [...tree] })

			//更新often
			const preList = useUserOftenStore.getState().list
			const keywords = useUserStore.getState().keywords
			let list = uniqBy([...preList, ...TranslatorAllToSimple(r)], (val) => val.uuid)
			setSearchStatusInSimple(list, keywords)
			useUserOftenStore.setState({ list })
		}
	}

	vipSort2Users()
}

export const setDcsList = (list: UserEntity[]) => {
	const { dcs_members, getEnableMembers } = useMeetingDcsStore.getState()
	//去除会议和能否拖拽判断
	list = list.filter((x) => canAdd(x) && x.account_type !== 10)
	let result = uniqBy(list, (x) => `${x.account_type}$$${x.account}`)
	if (result.length > 32) {
		Alert(t('协作成员仅限32方，请删除不必要的协作人员后再操作'))
		return
	}
	let addList = differenceBy(result, dcs_members, (x) => `${x.account_type}$$${x.account}`)
	if (addList.length > 0) {
		getEnableMembers(addList, function (mts) {
			useMeetingDcsStore.setState({ dcs_members: [...dcs_members, ...mts] })
		})
	}
}

export const setVlList = (list: UserEntity[]) => {
	//去除会议
	list = list.filter((x) => x.account_type !== 10)
	let result = uniqBy(list, (x) => `${x.account_type}$$${x.account}`)
	useMeetingLiveVideoStore.setState({ live_members: result })
}

export const setMixList = (list: UserEntity[]) => {
	//去除会议和能否拖拽判断
	list = list.filter((x) => canAdd(x) && x.account_type !== 10)
	let result = uniqBy(list, (x) => `${x.account_type}$$${x.account}`)
	useMeetingMixStore.setState({ members: result })
}

export const setPollList = (list: UserEntity[]) => {
	//去除会议和能否拖拽判断
	list = list.filter((x) => canAdd(x) && x.account_type !== 10)
	let result = uniqBy(list, (x) => `${x.account_type}$$${x.account}`)
	useMeetingPollStore.setState({ memberList: result })
}

export const setKcList = (list: UserEntity[]) => {
	//可能是常用终端直接拖过来，所以只能遍历下看下是否存在于本级
	const tree = useUserAllStore.getState().tree
	const uuids = tree.map((x) => x.uuid)
	//可以拖拽非互动
	list = list.filter((x) => uuids.includes(`${x.account_type}$$${x.account}`) && x.account_type !== 10)
	let result = uniqBy(list, (x) => `${x.account_type}$$${x.account}`)
	useMeetingParamsStore.setState({ keep_calling_members: result })
}

export const setVmpPollList = (list: UserEntity[]) => {
	//可能是常用终端直接拖过来，所以只能遍历下看下是否存在于本级
	const tree = useUserAllStore.getState().tree
	const uuids = tree.map((x) => x.uuid)
	list = list.filter((x) => canAdd(x) && uuids.includes(`${x.account_type}$$${x.account}`) && x.account_type !== 10)
	let result = uniqBy(list, (x) => `${x.account_type}$$${x.account}`)
	useMeetingVmpStore.getState().setBatchPollParams({ members: result })
}

export const setTvwallPollList = (list: UserEntity[]) => {
	//可能是常用终端直接拖过来，所以只能遍历下看下是否存在于本级
	const tree = useUserAllStore.getState().tree
	const uuids = tree.map((x) => x.uuid)

	list = list.filter((x) => canAdd(x) && uuids.includes(`${x.account_type}$$${x.account}`) && x.account_type !== 10)
	let result = uniqBy(list, (x) => `${x.account_type}$$${x.account}`)
	const cashData = useMeetingTVWallStore.getState().operate_correct_style_info
	setBatchPollMemeberCash(result)
	useMeetingTVWallStore.setState({ pollMembers: result })
}

/**vip的顺序，更新全部终端/常用终端/互动终端 */
export const vipSort2Users = () => {
	const { vipList, superMtNum } = useBasicInfoStore.getState()
	if (vipList.length > 0) {
		const arr = vipList.map((x) => `${x.account_type}$$${x.account}`)
		const tree = useUserAllStore.getState().tree

		let Vips = tree.filter((x) => arr.includes(x.uuid))
		//user里的 vip 和 vip列表的vip 不一定一致，以 user 里的为主，vip列表为辅
		let _arr = Array(Vips.length)
		for (const vip of Vips) {
			const index = arr.findIndex((uuid) => uuid === vip.uuid)
			if (index !== -1) {
				_arr[index] = vip
			} else {
				_arr.push(vip)
			}
		}
		Vips = _arr.filter(Boolean)
		let noVips = tree.filter((x) => !arr.includes(x.uuid))

		useUserAllStore.setState({ tree: [...Vips, ...noVips] })

		//更新 often/interactive
		let simpleStore = superMtNum ? useUserInteractiveStore : useUserOftenStore
		const preList = simpleStore.getState().list
		let Vips2 = preList.filter((x) => arr.includes(x.uuid))
		let _arr2 = Array(Vips2.length)
		for (const vip of Vips2) {
			const index = arr.findIndex((uuid) => uuid === vip.uuid)
			if (index !== -1) {
				_arr2[index] = vip
			} else {
				_arr2.push(vip)
			}
		}
		Vips2 = _arr2.filter(Boolean)
		let noVips2 = preList.filter((x) => !arr.includes(x.uuid))
		simpleStore.setState({ list: [...Vips2, ...noVips2] })
	}
}
